﻿#if SILVERLIGHT
//------------------------------------------------------------------------------
//  Microsoft Avalon
//  Copyright (c) Microsoft Corporation, 2003
//
//  File: PixelFormat.cs
//
//-----------------------------------------------------------------------------
//for petra.Gis updated by asida@centrum.cz (as PixelFormat unavailable in SL4)

#pragma warning disable 1634, 1691 // Allow suppression of certain presharp messages
 
using System;
using System.Security;
using System.Security.Permissions;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Reflection;
//using MS.Internal;
//using MS.Win32;
using System.Diagnostics;
//using System.Windows.Media;
using System.Globalization;
using System.Runtime.InteropServices;
 
//using SR=MS.Internal.PresentationCore.SR; //error msg
//using SRID=MS.Internal.PresentationCore.SRID; //error SRID
//using UnsafeNativeMethods=MS.Win32.PresentationCore.UnsafeNativeMethods;
  
//namespace System.Windows.Media
namespace Petra.Gis.Geometry.GridSupport
{



  [System.Flags]
  internal enum PixelFormatFlags
  {
    BitsPerPixelMask = 0x00FF,
    BitsPerPixelUndefined = 0,
    BitsPerPixel1 = 1,
    BitsPerPixel2 = 2,
    BitsPerPixel4 = 4,
    BitsPerPixel8 = 8,
    BitsPerPixel16 = 16,
    BitsPerPixel24 = 24,
    BitsPerPixel32 = 32,
    BitsPerPixel48 = 48,
    BitsPerPixel64 = 64,
    BitsPerPixel96 = 96,
    BitsPerPixel128 = 128,
    IsGray = 0x00000100,   // Grayscale only
    IsCMYK = 0x00000200,   // CMYK, not ARGB
    IsSRGB = 0x00000400,   // Gamma is approximately 2.2
    IsScRGB = 0x00000800,   // Gamma is 1.0
    Premultiplied = 0x00001000,   // Premultiplied Alpha
    ChannelOrderMask = 0x0001E000,
    ChannelOrderRGB = 0x00002000,
    ChannelOrderBGR = 0x00004000,
    ChannelOrderARGB = 0x00008000,
    ChannelOrderABGR = 0x00010000,
    Palettized = 0x00020000,   // Pixels are indexes into a palette
    NChannelAlpha = 0x00040000,   // N-Channel format with alpha
    IsNChannel = 0x00080000,   // N-Channel format
  }





#region PixelFormat


  /// <summary>
  /// Describes the bit mask and shift for a specific pixelformat
  /// </summary>
  public struct PixelFormatChannelMask
  {

    internal PixelFormatChannelMask(byte[] mask)
    {
      Debug.Assert(mask != null);
      m_mask = mask;
    }



    /// <summary>
    /// The bitmask for a color channel
    /// It will never be greater then 0xffffffff
    /// </summary>
    public IList<byte> Mask
    {
      get
      {
        return new List<byte>((byte[])m_mask.Clone());
      }
    }





    /// <summary>
    /// op_equality - returns whether or not the two pixel format channel masks are equal
    /// </summary>
    public static bool operator ==(PixelFormatChannelMask left, PixelFormatChannelMask right)
    {
      Object o1 = left;
      Object o2 = right;

      if (o1 == null)
      {
        return (o2 == null);
      }
      else if (o2 == null)
      {
        return false;
      }
      else
      {
#pragma warning disable 6506
        return left.m_mask.Equals(right.m_mask);
#pragma warning restore 6506
      }
    }





    /// <summary>
    /// Equals - Returns whether or not the two pixel format channel masks are equal
    /// </summary>
    public static bool Equals(PixelFormatChannelMask left, PixelFormatChannelMask right)
    {
      Object o1 = left;
      Object o2 = right;

      if (o1 == null)
      {
        return (o2 == null);
      }
      else if (o2 == null)
      {
        return false;
      }
      else
      {
#pragma warning disable 6506
        return left.m_mask.Equals(right.m_mask);
#pragma warning restore 6506
      }
    }




    /// <summary>
    /// op_inequality - returns whether or not the two pixel format channel masks are not equal
    /// </summary>
    public static bool operator !=(PixelFormatChannelMask left, PixelFormatChannelMask right)
    {
      return !(left == right);
    }




    /// <summary>
    /// Equals - Returns whether or not this is equal to the Object
    /// </summary>
    public override bool Equals(Object obj)
    {
      if ((null == obj) ||
          !(obj is PixelFormatChannelMask))
      {
        return false;
      }

      return this == (PixelFormatChannelMask)obj;
    }




    /// <summary>
    /// GetHashCode - Returns a hash code
    /// </summary>
    public override int GetHashCode()
    {
      int hash = 0;

      for (int i = 0; i < m_mask.Length; i++)
      {
        hash += m_mask[i];
      }
      return hash;

    }

    private byte[] m_mask;

  }





  /// Pixel Format Definition for images and pixel-based surfaces
  ///
  [TypeConverter(typeof(PixelFormatConverter))]
  [Serializable]
  public struct PixelFormat : IEquatable<PixelFormat>
  {


    /// <securitynote>
    /// Critical - Accesses closely controlled format guid
    /// </securitynote>
    [SecurityCritical]
    internal PixelFormat(Guid guidPixelFormat)
    {
      bool fBuiltIn = true;

      byte[] guidBytes = guidPixelFormat.ToByteArray();
      byte[] guidBuiltIn = WICPixelFormatGUIDs.WICPixelFormatDontCare.ToByteArray();

      // If it's a built-in format, identify the pixel format enum.
      for (int i = 0; i < guidBytes.Length - 1; i++)
      {
        if (guidBytes[i] != guidBuiltIn[i])
          fBuiltIn = false;

        break;
      }
      if (guidBytes[guidBytes.Length - 1] > (byte)PixelFormatEnum.Cmyk32)
      {
        fBuiltIn = false;
      }

      if (fBuiltIn)
      {
        m_format = (PixelFormatEnum)guidBytes[guidBytes.Length - 1];
      }
      else
      {
        m_format = PixelFormatEnum.Extended;
      }

      m_flags = GetPixelFormatFlagsFromEnum(m_format) | GetPixelFormatFlagsFromGuid(guidPixelFormat);
      m_bitsPerPixel = GetBitsPerPixelFromEnum(m_format);
      //m_guidFormat = new SecurityCriticalDataForSet<guid>(guidPixelFormat);
      m_guidFormat = guidPixelFormat;
    }





    /// <securitynote>
    /// Critical - Accesses closely controlled format guid
    /// TreatAsSafe - The input (enum) is validated in setting the format guid
    /// </securitynote>
    //[SecurityCritical, SecurityTreatAsSafe]
    internal PixelFormat(PixelFormatEnum format)
    {
      m_format = format;

      m_flags = GetPixelFormatFlagsFromEnum(format);
      m_bitsPerPixel = GetBitsPerPixelFromEnum(format);
      //m_guidFormat = new SecurityCriticalDataForSet<guid>(PixelFormat.GetGuidFromFormat(format));
      m_guidFormat = PixelFormat.GetGuidFromFormat(format);
    }





    /// <summary>
    /// Construct a pixel format from a string that represents the format.
    /// The purpose of this method is only for deserialization of PixelFormat.
    /// The preferred way to construct a PixelFormat is with the PixelFormats class.
    /// </summary>
    /// <param name="pixelFormatString">
    /// <securitynote>
    /// Critical - Accesses closely controlled format guid
    /// TreatAsSafe - The input (string) is validated in setting the format guid
    /// </securitynote>
    //[SecurityCritical, SecurityTreatAsSafe]
    internal PixelFormat(string pixelFormatString)
    {
      PixelFormatEnum format = PixelFormatEnum.Default;

      if (pixelFormatString == null)
      {
        throw new System.ArgumentNullException("pixelFormatString");
      }

      string upperPixelFormatString = pixelFormatString.ToUpper(System.Globalization.CultureInfo.InvariantCulture);

      switch (upperPixelFormatString)
      {
        case "DEFAULT":
          format = PixelFormatEnum.Default;
          break;

        case "EXTENDED":
          format = PixelFormatEnum.Extended;
          break;

        case "INDEXED1":
          format = PixelFormatEnum.Indexed1;
          break;

        case "INDEXED2":
          format = PixelFormatEnum.Indexed2;
          break;

        case "INDEXED4":
          format = PixelFormatEnum.Indexed4;
          break;

        case "INDEXED8":
          format = PixelFormatEnum.Indexed8;
          break;

        case "BLACKWHITE":
          format = PixelFormatEnum.BlackWhite;
          break;

        case "GRAY2":
          format = PixelFormatEnum.Gray2;
          break;

        case "GRAY4":
          format = PixelFormatEnum.Gray4;
          break;

        case "GRAY8":
          format = PixelFormatEnum.Gray8;
          break;

        case "BGR555":
          format = PixelFormatEnum.Bgr555;
          break;

        case "BGR565":
          format = PixelFormatEnum.Bgr565;
          break;

        case "BGR24":
          format = PixelFormatEnum.Bgr24;
          break;

        case "RGB24":
          format = PixelFormatEnum.Rgb24;
          break;

        case "BGR101010":
          format = PixelFormatEnum.Bgr101010;
          break;

        case "BGR32":
          format = PixelFormatEnum.Bgr32;
          break;

        case "BGRA32":
          format = PixelFormatEnum.Bgra32;
          break;

        case "PBGRA32":
          format = PixelFormatEnum.Pbgra32;
          break;

        case "RGB48":
          format = PixelFormatEnum.Rgb48;
          break;

        case "RGBA64":
          format = PixelFormatEnum.Rgba64;
          break;

        case "PRGBA64":
          format = PixelFormatEnum.Prgba64;
          break;

        case "GRAY16":
          format = PixelFormatEnum.Gray16;
          break;

        case "GRAY32FLOAT":
          format = PixelFormatEnum.Gray32Float;
          break;

        case "RGB128FLOAT":
          format = PixelFormatEnum.Rgb128Float;
          break;

        case "RGBA128FLOAT":
          format = PixelFormatEnum.Rgba128Float;
          break;

        case "PRGBA128FLOAT":
          format = PixelFormatEnum.Prgba128Float;
          break;

        case "CMYK32":
          format = PixelFormatEnum.Cmyk32;
          break;

        default:
          throw new System.ArgumentException(SR.Get(SRID.Image_BadPixelFormat, pixelFormatString),
                  "pixelFormatString");

      }

      m_format = format;

      m_flags = GetPixelFormatFlagsFromEnum(format);
      m_bitsPerPixel = GetBitsPerPixelFromEnum(format);
      //m_guidFormat = new SecurityCriticalDataForSet<guid>(PixelFormat.GetGuidFromFormat(format));
      m_guidFormat = PixelFormat.GetGuidFromFormat(format);
    }





    static private Guid GetGuidFromFormat(PixelFormatEnum format)
    {
      switch (format)
      {
        case PixelFormatEnum.Default:
          return WICPixelFormatGUIDs.WICPixelFormatDontCare;

        case PixelFormatEnum.Indexed1:
          return WICPixelFormatGUIDs.WICPixelFormat1bppIndexed;

        case PixelFormatEnum.Indexed2:
          return WICPixelFormatGUIDs.WICPixelFormat2bppIndexed;

        case PixelFormatEnum.Indexed4:
          return WICPixelFormatGUIDs.WICPixelFormat4bppIndexed;

        case PixelFormatEnum.Indexed8:
          return WICPixelFormatGUIDs.WICPixelFormat8bppIndexed;

        case PixelFormatEnum.BlackWhite:
          return WICPixelFormatGUIDs.WICPixelFormatBlackWhite;

        case PixelFormatEnum.Gray2:
          return WICPixelFormatGUIDs.WICPixelFormat2bppGray;

        case PixelFormatEnum.Gray4:
          return WICPixelFormatGUIDs.WICPixelFormat4bppGray;

        case PixelFormatEnum.Gray8:
          return WICPixelFormatGUIDs.WICPixelFormat8bppGray;

        case PixelFormatEnum.Bgr555:
          return WICPixelFormatGUIDs.WICPixelFormat16bppBGR555;

        case PixelFormatEnum.Bgr565:
          return WICPixelFormatGUIDs.WICPixelFormat16bppBGR565;

        case PixelFormatEnum.Bgr24:
          return WICPixelFormatGUIDs.WICPixelFormat24bppBGR;

        case PixelFormatEnum.Rgb24:
          return WICPixelFormatGUIDs.WICPixelFormat24bppRGB;

        case PixelFormatEnum.Bgr101010:
          return WICPixelFormatGUIDs.WICPixelFormat32bppBGR101010;

        case PixelFormatEnum.Bgr32:
          return WICPixelFormatGUIDs.WICPixelFormat32bppBGR;

        case PixelFormatEnum.Bgra32:
          return WICPixelFormatGUIDs.WICPixelFormat32bppBGRA;

        case PixelFormatEnum.Pbgra32:
          return WICPixelFormatGUIDs.WICPixelFormat32bppPBGRA;

        case PixelFormatEnum.Rgb48:
          return WICPixelFormatGUIDs.WICPixelFormat48bppRGB;

        case PixelFormatEnum.Rgba64:
          return WICPixelFormatGUIDs.WICPixelFormat64bppRGBA;

        case PixelFormatEnum.Prgba64:
          return WICPixelFormatGUIDs.WICPixelFormat64bppPRGBA;

        case PixelFormatEnum.Gray16:
          return WICPixelFormatGUIDs.WICPixelFormat16bppGray;

        case PixelFormatEnum.Gray32Float:
          return WICPixelFormatGUIDs.WICPixelFormat32bppGrayFloat;

        case PixelFormatEnum.Rgb128Float:
          return WICPixelFormatGUIDs.WICPixelFormat128bppRGBFloat;

        case PixelFormatEnum.Rgba128Float:
          return WICPixelFormatGUIDs.WICPixelFormat128bppRGBAFloat;

        case PixelFormatEnum.Prgba128Float:
          return WICPixelFormatGUIDs.WICPixelFormat128bppPRGBAFloat;

        case PixelFormatEnum.Cmyk32:
          return WICPixelFormatGUIDs.WICPixelFormat32bppCMYK;
      }

      throw new System.ArgumentException(SR.Get(SRID.Image_BadPixelFormat, format), "format");
    }





    private PixelFormatFlags FormatFlags
    {
      get
      {
        return m_flags;
      }
    }





    /// <summary>
    /// op_equality - returns whether or not the two pixel formats are equal
    /// </summary>
    public static bool operator ==(PixelFormat left, PixelFormat right)
    {
      return (left.Guid == right.Guid);
    }




    /// <summary>
    /// op_inequality - returns whether or not the two pixel formats are not equal
    /// </summary>
    public static bool operator !=(PixelFormat left, PixelFormat right)
    {
      return (left.Guid != right.Guid);
    }




    /// <summary>
    /// Equals - Returns whether or not the two pixel formats are equal
    /// </summary>
    public static bool Equals(PixelFormat left, PixelFormat right)
    {
      return (left.Guid == right.Guid);
    }




    /// <summary>
    /// Equals - Returns whether or not this is equal to the PixelFormat
    /// </summary>
    public bool Equals(PixelFormat pixelFormat)
    {
      return this == pixelFormat;
    }




    /// <summary>
    /// Equals - Returns whether or not this is equal to the Object
    /// </summary>
    public override bool Equals(Object obj)
    {
      if ((null == obj) ||
          !(obj is PixelFormat))
      {
        return false;
      }

      return this == (PixelFormat)obj;
    }




    /// <summary>
    /// GetHashCode - Returns a hash code
    /// </summary>
    public override int GetHashCode()
    {
      int hash = 0;

      byte[] guidBytes = Guid.ToByteArray();

      for (int i = 0; i < guidBytes.Length; i++)
        hash += (int)guidBytes[i];

      return hash;
    }




    /// The number of bits per pixel for this format.
    ///
    /// <securitynote>
    /// Critical - Access unmanaged code
    /// PublicOK - the pixel format info (an exsternal input) comes from a critical function which creates it based on the pixel format GUID
    ///   and has a TAS boundary tracking all setting of it.
    /// LinkDemand - blocks information disclosure in partial trust scenario
    /// </securitynote>
    public int BitsPerPixel
    {
      [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
      [SecurityCritical]
      get
      {
        //return InternalBitsPerPixel;
        throw new NotImplementedException();
      }
    }




    /// <summary>
    /// The pixel format mask information for each channel.
    /// </summary>
    /// <securitynote>
    /// Critical - Access unmanaged code
    /// PublicOK - the pixel format info (an exsternal input) comes from a critical function which creates it based on the pixel format GUID
    ///   and has a TAS boundary tracking all setting of it.
    /// LinkDemand - blocks information disclosure in partial trust scenario
    /// </securitynote>
    public IList<PixelFormatChannelMask> Masks
    {
      [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
      [SecurityCritical]
      get
      {
        //IntPtr pixelFormatInfo = CreatePixelFormatInfo();
        //Debug.Assert(pixelFormatInfo != IntPtr.Zero);

        //UInt32 channelCount = 0;
        //PixelFormatChannelMask[] masks = null;
        //UInt32 cbBytes = 0;

        //try
        //{
        //  HRESULT.Check(UnsafeNativeMethods.WICPixelFormatInfo.GetChannelCount(
        //      pixelFormatInfo,
        //      out channelCount
        //      ));

        //  Debug.Assert(channelCount >= 1);

        //  masks = new PixelFormatChannelMask[channelCount];

        //  unsafe
        //  {
        //    for (uint i = 0; i < channelCount; i++)
        //    {
        //      HRESULT.Check(UnsafeNativeMethods.WICPixelFormatInfo.getchannelmask(pixelFormatInfo, i, 0, null, out cbBytes));
        //      Debug.Assert(cbBytes > 0);

        //      byte[] channelMask = new byte[cbBytes];

        //      fixed (byte* pbChannelMask = channelMask)
        //      {
        //        HRESULT.Check(UnsafeNativeMethods.WICPixelFormatInfo.GetChannelMask(
        //            pixelFormatInfo, i, cbBytes, pbChannelMask, out cbBytes));

        //        Debug.Assert(cbBytes == channelMask.Length);
        //      }

        //      masks[i] = new PixelFormatChannelMask(channelMask);
        //    }
        //  }
        //}
        //finally
        //{
        //  if (pixelFormatInfo != IntPtr.Zero)
        //  {
        //    UnsafeNativeMethods.MILUnknown.ReleaseInterface(ref pixelFormatInfo);
        //  }
        //}

        //return new List<PixelFormatChannelMask>(masks);

        throw new NotImplementedException();
      }
    }





    ///// <securitynote>
    ///// Critical - Access unmanaged code
    ///// </securitynote>
    //[SecurityCritical]
    //internal IntPtr CreatePixelFormatInfo()
    //{
    //  IntPtr componentInfo = IntPtr.Zero;
    //  IntPtr pixelFormatInfo = IntPtr.Zero;

    //  using (FactoryMaker myFactory = new FactoryMaker())
    //  {
    //    try
    //    {
    //      Guid guidPixelFormat = this.Guid;

    //      int hr = UnsafeNativeMethods.WICImagingFactory.CreateComponentInfo(
    //          myFactory.ImagingFactoryPtr,
    //          ref guidPixelFormat,
    //          out componentInfo);
    //      if (hr == (int)WinCodecErrors.WINCODEC_ERR_COMPONENTINITIALIZEFAILURE ||
    //          hr == (int)WinCodecErrors.WINCODEC_ERR_COMPONENTNOTFOUND)
    //      {
    //        throw new System.NotSupportedException(SR.Get(SRID.Image_NoPixelFormatFound));
    //      }
    //      HRESULT.Check(hr);

    //      Guid guidPixelFormatInfo = MILGuidData.IID_IWICPixelFormatInfo;
    //      HRESULT.Check(UnsafeNativeMethods.MILUnknown.QueryInterface(
    //          componentInfo,
    //          ref guidPixelFormatInfo,
    //          out pixelFormatInfo));
    //    }
    //    finally
    //    {
    //      if (componentInfo != IntPtr.Zero)
    //      {
    //        UnsafeNativeMethods.MILUnknown.ReleaseInterface(ref componentInfo);
    //      }
    //    }
    //  }

    //  return pixelFormatInfo;
    //}




    ///// <securitynote>
    ///// Critical - Access unmanaged code
    ///// </securitynote>
    //internal int InternalBitsPerPixel
    //{
    //  [SecurityCritical]
    //  get
    //  {
    //    if (m_bitsPerPixel == 0)
    //    {
    //      UInt32 bpp = 0;

    //      IntPtr pixelFormatInfo = CreatePixelFormatInfo();
    //      Debug.Assert(pixelFormatInfo != IntPtr.Zero);

    //      try
    //      {
    //        HRESULT.Check(UnsafeNativeMethods.WICPixelFormatInfo.GetBitsPerPixel(
    //            pixelFormatInfo,
    //            out bpp
    //            ));
    //      }
    //      finally
    //      {
    //        if (pixelFormatInfo != IntPtr.Zero)
    //        {
    //          UnsafeNativeMethods.MILUnknown.ReleaseInterface(ref pixelFormatInfo);
    //        }
    //      }

    //      m_bitsPerPixel = bpp;
    //    }

    //    return (int)m_bitsPerPixel;
    //  }
    //}




    internal bool HasAlpha
    {
      get
      {
        return ((FormatFlags & PixelFormatFlags.ChannelOrderABGR) != 0 ||
                    (FormatFlags & PixelFormatFlags.ChannelOrderARGB) != 0 ||
                    (FormatFlags & PixelFormatFlags.NChannelAlpha) != 0);
      }
    }




    internal bool Palettized
    {
      get
      {
        return ((FormatFlags & PixelFormatFlags.Palettized) != 0);
      }
    }




    internal PixelFormatEnum Format
    {
      get
      {
        return m_format;
      }
    }




    internal Guid Guid
    {
      get
      {
        //return m_guidFormat.Value;
        return m_guidFormat;
      }
    }




    /// <summary>
    /// Convert a PixelFormat to a string that represents it.
    /// </summary>
    /// <returns></returns>
    public override string ToString()
    {
      return m_format.ToString();
    }




    ///// <securitynote>
    ///// Critical - calls unmanaged code, accepts unmanaged handles as arguments
    ///// </securitynote>
    //[SecurityCritical]
    //internal static PixelFormat GetPixelFormat(
    //    SafeMILHandle /* IWICBitmapSource */ bitmapSource
    //    )
    //{
    //  Guid guidPixelFormat = WICPixelFormatGUIDs.WICPixelFormatDontCare;

    //  HRESULT.Check(UnsafeNativeMethods.WICBitmapSource.GetPixelFormat(bitmapSource, out guidPixelFormat));

    //  return new PixelFormat(guidPixelFormat);
    //}





    /// <summary>
    /// Convert from the internal guid to the actual PixelFormat value.
    /// </summary>
    /// <param name="pixelFormatGuid">
    /// <returns></returns>
    internal static PixelFormat GetPixelFormat(Guid pixelFormatGuid)
    {
      byte[] guidBytes = pixelFormatGuid.ToByteArray();
      return GetPixelFormat((PixelFormatEnum)guidBytes[guidBytes.Length - 1]);
    }





    /// <summary>
    /// Convert from the internal enum to the actual PixelFormat value.
    /// </summary>
    /// <param name="pixelFormatEnum">
    /// <returns></returns>
    internal static PixelFormat GetPixelFormat(PixelFormatEnum pixelFormatEnum)
    {
      switch (pixelFormatEnum)
      {
        case PixelFormatEnum.Indexed1:
          return PixelFormats.Indexed1;

        case PixelFormatEnum.Indexed2:
          return PixelFormats.Indexed2;

        case PixelFormatEnum.Indexed4:
          return PixelFormats.Indexed4;

        case PixelFormatEnum.Indexed8:
          return PixelFormats.Indexed8;

        case PixelFormatEnum.BlackWhite:
          return PixelFormats.BlackWhite;

        case PixelFormatEnum.Gray2:
          return PixelFormats.Gray2;

        case PixelFormatEnum.Gray4:
          return PixelFormats.Gray4;

        case PixelFormatEnum.Gray8:
          return PixelFormats.Gray8;

        case PixelFormatEnum.Bgr555:
          return PixelFormats.Bgr555;

        case PixelFormatEnum.Bgr565:
          return PixelFormats.Bgr565;

        case PixelFormatEnum.Bgr101010:
          return PixelFormats.Bgr101010;

        case PixelFormatEnum.Bgr24:
          return PixelFormats.Bgr24;

        case PixelFormatEnum.Rgb24:
          return PixelFormats.Rgb24;

        case PixelFormatEnum.Bgr32:
          return PixelFormats.Bgr32;

        case PixelFormatEnum.Bgra32:
          return PixelFormats.Bgra32;

        case PixelFormatEnum.Pbgra32:
          return PixelFormats.Pbgra32;

        case PixelFormatEnum.Rgb48:
          return PixelFormats.Rgb48;

        case PixelFormatEnum.Rgba64:
          return PixelFormats.Rgba64;

        case PixelFormatEnum.Prgba64:
          return PixelFormats.Prgba64;

        case PixelFormatEnum.Gray16:
          return PixelFormats.Gray16;

        case PixelFormatEnum.Gray32Float:
          return PixelFormats.Gray32Float;

        case PixelFormatEnum.Rgb128Float:
          return PixelFormats.Rgb128Float;

        case PixelFormatEnum.Rgba128Float:
          return PixelFormats.Rgba128Float;

        case PixelFormatEnum.Prgba128Float:
          return PixelFormats.Prgba128Float;

        case PixelFormatEnum.Cmyk32:
          return PixelFormats.Cmyk32;
      }

      return PixelFormats.Default;
    }





    static private PixelFormatFlags GetPixelFormatFlagsFromGuid(Guid pixelFormatGuid)
    {
      PixelFormatFlags result = PixelFormatFlags.BitsPerPixelUndefined;

      if (pixelFormatGuid.CompareTo(WICPixelFormatPhotonFirst) >= 0 &&
                      pixelFormatGuid.CompareTo(WICPixelFormatPhotonLast) <= 0)
      {
        byte[] b = pixelFormatGuid.ToByteArray();

        switch (b[15])
        {
          case 0x1D:  // GUID_WICPixelFormat64bppRGBAFixedPoint
            result = PixelFormatFlags.ChannelOrderARGB | PixelFormatFlags.IsScRGB;
            break;
          case 0x1E:  // GUID_WICPixelFormat128bppRGBAFixedPoint
            result = PixelFormatFlags.ChannelOrderARGB | PixelFormatFlags.IsScRGB;
            break;
          case 0x1F:  // GUID_WICPixelFormat64bppCMYK
            result = PixelFormatFlags.IsCMYK;
            break;
          case 0x20:  // GUID_WICPixelFormat24bpp3Channels
            result = PixelFormatFlags.IsNChannel;
            break;
          case 0x21:  // GUID_WICPixelFormat32bpp4Channels
            result = PixelFormatFlags.IsNChannel;
            break;
          case 0x22:  // GUID_WICPixelFormat40bpp5Channels
            result = PixelFormatFlags.IsNChannel;
            break;
          case 0x23:  // GUID_WICPixelFormat48bpp6Channels
            result = PixelFormatFlags.IsNChannel;
            break;
          case 0x24:  // GUID_WICPixelFormat56bpp7Channels
            result = PixelFormatFlags.IsNChannel;
            break;
          case 0x25:  // GUID_WICPixelFormat64bpp8Channels
            result = PixelFormatFlags.IsNChannel;
            break;
          case 0x26:  // GUID_WICPixelFormat48bpp3Channels
            result = PixelFormatFlags.IsNChannel;
            break;
          case 0x27:  // GUID_WICPixelFormat64bpp4Channels
            result = PixelFormatFlags.IsNChannel;
            break;
          case 0x28:  // GUID_WICPixelFormat80bpp5Channels
            result = PixelFormatFlags.IsNChannel;
            break;
          case 0x29:  // GUID_WICPixelFormat96bpp6Channels
            result = PixelFormatFlags.IsNChannel;
            break;
          case 0x2A:  // GUID_WICPixelFormat112bpp7Channels
            result = PixelFormatFlags.IsNChannel;
            break;
          case 0x2B:  // GUID_WICPixelFormat128bpp8Channels
            result = PixelFormatFlags.IsNChannel;
            break;
          case 0x2C:  // GUID_WICPixelFormat40bppCMYKAlpha
            result = PixelFormatFlags.IsCMYK | PixelFormatFlags.NChannelAlpha;
            break;
          case 0x2D:  // GUID_WICPixelFormat80bppCMYKAlpha
            result = PixelFormatFlags.IsCMYK | PixelFormatFlags.NChannelAlpha;
            break;
          case 0x2E:  // GUID_WICPixelFormat32bpp3ChannelsAlpha
            result = PixelFormatFlags.IsNChannel | PixelFormatFlags.NChannelAlpha;
            break;
          case 0x2F:  // GUID_WICPixelFormat40bpp4ChannelsAlpha
            result = PixelFormatFlags.IsNChannel | PixelFormatFlags.NChannelAlpha;
            break;
          case 0x30:  // GUID_WICPixelFormat48bpp5ChannelsAlpha
            result = PixelFormatFlags.IsNChannel | PixelFormatFlags.NChannelAlpha;
            break;
          case 0x31:  // GUID_WICPixelFormat56bpp6ChannelsAlpha
            result = PixelFormatFlags.IsNChannel | PixelFormatFlags.NChannelAlpha;
            break;
          case 0x32:  // GUID_WICPixelFormat64bpp7ChannelsAlpha
            result = PixelFormatFlags.IsNChannel | PixelFormatFlags.NChannelAlpha;
            break;
          case 0x33:  // GUID_WICPixelFormat72bpp8ChannelsAlpha
            result = PixelFormatFlags.IsNChannel | PixelFormatFlags.NChannelAlpha;
            break;
          case 0x34:  // GUID_WICPixelFormat64bpp3ChannelsAlpha
            result = PixelFormatFlags.IsNChannel | PixelFormatFlags.NChannelAlpha;
            break;
          case 0x35:  // GUID_WICPixelFormat80bpp4ChannelsAlpha
            result = PixelFormatFlags.IsNChannel | PixelFormatFlags.NChannelAlpha;
            break;
          case 0x36:  // GUID_WICPixelFormat96bpp5ChannelsAlpha
            result = PixelFormatFlags.IsNChannel | PixelFormatFlags.NChannelAlpha;
            break;
          case 0x37:  // GUID_WICPixelFormat112bpp6ChannelsAlpha
            result = PixelFormatFlags.IsNChannel | PixelFormatFlags.NChannelAlpha;
            break;
          case 0x38:  // GUID_WICPixelFormat128bpp7ChannelsAlpha
            result = PixelFormatFlags.IsNChannel | PixelFormatFlags.NChannelAlpha;
            break;
          case 0x39:  // GUID_WICPixelFormat144bpp8ChannelsAlpha
            result = PixelFormatFlags.IsNChannel | PixelFormatFlags.NChannelAlpha;
            break;
          case 0x3A:  // GUID_WICPixelFormat64bppRGBAHalf
            result = PixelFormatFlags.ChannelOrderARGB | PixelFormatFlags.IsScRGB;
            break;
          case 0x3B:  // GUID_WICPixelFormat48bppRGBHalf
            result = PixelFormatFlags.ChannelOrderRGB | PixelFormatFlags.IsScRGB;
            break;
          case 0x3D:  // GUID_WICPixelFormat32bppRGBE
            result = PixelFormatFlags.ChannelOrderRGB | PixelFormatFlags.IsScRGB;
            break;
          case 0x3E:  // GUID_WICPixelFormat16bppGrayHalf
            result = PixelFormatFlags.IsGray | PixelFormatFlags.IsScRGB;
            break;
          case 0x3F:  // GUID_WICPixelFormat32bppGrayFixedPoint
            result = PixelFormatFlags.IsGray | PixelFormatFlags.IsScRGB;
            break;
          case 0x40:  // GUID_WICPixelFormat64bppRGBFixedPoint
            result = PixelFormatFlags.IsScRGB | PixelFormatFlags.ChannelOrderRGB;
            break;
          case 0x41:  // GUID_WICPixelFormat128bppRGBFixedPoint
            result = PixelFormatFlags.IsScRGB | PixelFormatFlags.ChannelOrderRGB;
            break;
          case 0x42:  // GUID_WICPixelFormat64bppRGBHalf
            result = PixelFormatFlags.IsScRGB | PixelFormatFlags.ChannelOrderRGB;
            break;
        }
      }

      return result;
    }




    static private PixelFormatFlags GetPixelFormatFlagsFromEnum(PixelFormatEnum pixelFormatEnum)
    {
      switch (pixelFormatEnum)
      {
        case PixelFormatEnum.Default:
          return PixelFormatFlags.BitsPerPixelUndefined;

        case PixelFormatEnum.Indexed1:
          return PixelFormatFlags.BitsPerPixel1 | PixelFormatFlags.Palettized;

        case PixelFormatEnum.Indexed2:
          return PixelFormatFlags.BitsPerPixel2 | PixelFormatFlags.Palettized;

        case PixelFormatEnum.Indexed4:
          return PixelFormatFlags.BitsPerPixel4 | PixelFormatFlags.Palettized;

        case PixelFormatEnum.Indexed8:
          return PixelFormatFlags.BitsPerPixel8 | PixelFormatFlags.Palettized;

        case PixelFormatEnum.BlackWhite:
          return PixelFormatFlags.BitsPerPixel1 | PixelFormatFlags.IsGray;

        case PixelFormatEnum.Gray2:
          return PixelFormatFlags.BitsPerPixel2 | PixelFormatFlags.IsGray;

        case PixelFormatEnum.Gray4:
          return PixelFormatFlags.BitsPerPixel4 | PixelFormatFlags.IsGray;

        case PixelFormatEnum.Gray8:
          return PixelFormatFlags.BitsPerPixel8 | PixelFormatFlags.IsGray;

        case PixelFormatEnum.Bgr555:
          return PixelFormatFlags.BitsPerPixel16 | PixelFormatFlags.IsSRGB | PixelFormatFlags.ChannelOrderBGR;

        case PixelFormatEnum.Bgr565:
          return PixelFormatFlags.BitsPerPixel16 | PixelFormatFlags.IsSRGB | PixelFormatFlags.ChannelOrderBGR;

        case PixelFormatEnum.Bgr101010:
          return PixelFormatFlags.BitsPerPixel32 | PixelFormatFlags.IsSRGB | PixelFormatFlags.ChannelOrderBGR;

        case PixelFormatEnum.Bgr24:
          return PixelFormatFlags.BitsPerPixel24 | PixelFormatFlags.IsSRGB | PixelFormatFlags.ChannelOrderBGR;

        case PixelFormatEnum.Rgb24:
          return PixelFormatFlags.BitsPerPixel24 | PixelFormatFlags.IsSRGB | PixelFormatFlags.ChannelOrderRGB;

        case PixelFormatEnum.Bgr32:
          return PixelFormatFlags.BitsPerPixel32 | PixelFormatFlags.IsSRGB | PixelFormatFlags.ChannelOrderBGR;

        case PixelFormatEnum.Bgra32:
          return PixelFormatFlags.BitsPerPixel32 | PixelFormatFlags.IsSRGB | PixelFormatFlags.ChannelOrderABGR;

        case PixelFormatEnum.Pbgra32:
          return PixelFormatFlags.BitsPerPixel32 | PixelFormatFlags.IsSRGB | PixelFormatFlags.Premultiplied | PixelFormatFlags.ChannelOrderABGR;

        case PixelFormatEnum.Rgb48:
          return PixelFormatFlags.BitsPerPixel48 | PixelFormatFlags.IsSRGB | PixelFormatFlags.ChannelOrderRGB;

        case PixelFormatEnum.Rgba64:
          return PixelFormatFlags.BitsPerPixel64 | PixelFormatFlags.IsSRGB | PixelFormatFlags.ChannelOrderARGB;

        case PixelFormatEnum.Prgba64:
          return PixelFormatFlags.BitsPerPixel64 | PixelFormatFlags.IsSRGB | PixelFormatFlags.Premultiplied | PixelFormatFlags.ChannelOrderARGB;

        case PixelFormatEnum.Gray16:
          return PixelFormatFlags.BitsPerPixel16 | PixelFormatFlags.IsSRGB | PixelFormatFlags.IsGray;

        case PixelFormatEnum.Gray32Float:
          return PixelFormatFlags.BitsPerPixel32 | PixelFormatFlags.IsScRGB | PixelFormatFlags.IsGray;

        case PixelFormatEnum.Rgb128Float:
          return PixelFormatFlags.BitsPerPixel128 | PixelFormatFlags.IsScRGB | PixelFormatFlags.ChannelOrderRGB;

        case PixelFormatEnum.Rgba128Float:
          return PixelFormatFlags.BitsPerPixel128 | PixelFormatFlags.IsScRGB | PixelFormatFlags.ChannelOrderARGB;

        case PixelFormatEnum.Prgba128Float:
          return PixelFormatFlags.BitsPerPixel128 | PixelFormatFlags.IsScRGB | PixelFormatFlags.Premultiplied | PixelFormatFlags.ChannelOrderARGB;

        case PixelFormatEnum.Cmyk32:
          return PixelFormatFlags.BitsPerPixel32 | PixelFormatFlags.IsCMYK;
      }

      // 3rd party pixel format -- we don't expose anything about it.
      return PixelFormatFlags.BitsPerPixelUndefined;
    }




    static private UInt32 GetBitsPerPixelFromEnum(PixelFormatEnum pixelFormatEnum)
    {
      switch (pixelFormatEnum)
      {
        case PixelFormatEnum.Default:
          return 0;

        case PixelFormatEnum.Indexed1:
          return 1;

        case PixelFormatEnum.Indexed2:
          return 2;

        case PixelFormatEnum.Indexed4:
          return 4;

        case PixelFormatEnum.Indexed8:
          return 8;

        case PixelFormatEnum.BlackWhite:
          return 1;

        case PixelFormatEnum.Gray2:
          return 2;

        case PixelFormatEnum.Gray4:
          return 4;

        case PixelFormatEnum.Gray8:
          return 8;

        case PixelFormatEnum.Bgr555:
        case PixelFormatEnum.Bgr565:
          return 16;

        case PixelFormatEnum.Bgr101010:
          return 32;

        case PixelFormatEnum.Bgr24:
        case PixelFormatEnum.Rgb24:
          return 24;

        case PixelFormatEnum.Bgr32:
        case PixelFormatEnum.Bgra32:
        case PixelFormatEnum.Pbgra32:
          return 32;

        case PixelFormatEnum.Rgb48:
          return 48;

        case PixelFormatEnum.Rgba64:
        case PixelFormatEnum.Prgba64:
          return 64;

        case PixelFormatEnum.Gray16:
          return 16;

        case PixelFormatEnum.Gray32Float:
          return 32;

        case PixelFormatEnum.Rgb128Float:
        case PixelFormatEnum.Rgba128Float:
        case PixelFormatEnum.Prgba128Float:
          return 128;

        case PixelFormatEnum.Cmyk32:
          return 32;
      }

      // 3rd party pixel format -- we don't expose anything about it.
      return 0;
    }




    [NonSerialized]
    private PixelFormatFlags m_flags;

    [NonSerialized]
    private PixelFormatEnum m_format;

    [NonSerialized]
    [SecurityCritical]
    private UInt32 m_bitsPerPixel;

    [NonSerialized]
    //private SecurityCriticalDataForSet<guid> m_guidFormat;
    private Guid m_guidFormat;

    [NonSerialized]
    private static readonly Guid WICPixelFormatPhotonFirst = new Guid(0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1d);

    [NonSerialized]
    private static readonly Guid WICPixelFormatPhotonLast = new Guid(0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x42);
  }
#endregion // PixelFormat
}

#endif